package com.intertid.scala

import java.util.Collection
import java.util.Map
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.Cookie
import java.util.List
import java.util.ArrayList
import java.util.Date
import java.util.Set
import com.intertid.mongodb.ProxyTag
import java.lang.reflect.Field

package object commons {

  def logout(message: Any) = println("@@@@Debug output [" + new Date() + "]:" + message);

  private def listForeach[T <: Object](list: List[T], function: (T) => Unit): Unit = {
    val it = list.iterator();
    while (it.hasNext()) {
      function(it.next());
    }
  }
  //  implicit def listFind[T <: Object](list: List[T]) = {
  //
  //    new {
  //
  //      def find(function: (T) => Boolean): Option[T] = {
  //        val it = list.iterator();
  //        while (it.hasNext()) {
  //          val value = (it.next());
  //
  //          if (function(value)) {
  //
  //            return Some(value);
  //          }
  //        }
  //
  //        return None;
  //      }
  //    }
  //  }

  //  implicit def set[T <: Object](set: Set[T]) = {
  //    new {
  //      def foreach(f: (T) => Unit): Unit = {
  //        val iter = set.iterator;
  //        while (iter.hasNext)
  //          f(iter.next().asInstanceOf[T]);
  //      }
  //    }
  //  }

  implicit def collection[T](list: Collection[T]) = {
    new {

      def findAll[U <: T: Manifest](f: (U) => Boolean): Collection[U] = {
        var result: Collection[U] = null;
        try {
          result = list.getClass().newInstance().asInstanceOf[Collection[U]];
        } catch { case e: Exception => { result = new ArrayList[U] } }
        val iter = list.iterator();
        while (iter.hasNext()) {
          val v = iter.next();
          if (manifest[U].erasure.isInstance(v)) {
            if (f(v.asInstanceOf[U])) {
              result.add(v.asInstanceOf[U]);
            }
          }
        }
        return result.asInstanceOf[Collection[U]];
      }

      def foreach(function: (T) => Unit) = {
        val iter = list.iterator()
        while (iter.hasNext())
          function(iter.next().asInstanceOf[T]);
      }

      def findItem(f: (T) => Boolean): Option[T] = {
        var result = None;

        val iter = list.iterator();

        while (iter.hasNext()) {
          val v = iter.next().asInstanceOf[T];

          if (f(v)) {
            return Some(v);
          }
        }
        return result;
      }

      def `for`(f: (T, Int) => Unit) = {
        val iter = list.iterator()
        var i: Int = 0;
        while (iter.hasNext()) {
          f(iter.next().asInstanceOf[T], i);
          i = i + 1;
        }
      }
    }

  }

  implicit def mapForeach[K <: Object, V <: Object](map: Map[K, V]) = {
    new {
      def foreach(f: (K, V) => Unit) = {
        val keyIter = map.keySet().iterator();
        while (keyIter.hasNext()) {
          val k = keyIter.next().asInstanceOf[K];
          val v = map.get(k).asInstanceOf[V];
          f(k, v);
        }
      }

      def findItemKey(f: (K, V) => Boolean): Option[K] = {
        val keyIter = map.keySet().iterator();
        while (keyIter.hasNext()) {
          val k = keyIter.next().asInstanceOf[K];
          val v = map.get(k).asInstanceOf[V];
          if (f(k, v)) {
            return Some(k);
          }
        }
        return None;
      }
    }
  }

  implicit def classGetReal(pc: Class[_]) = {
    new {
      def getRealClass(): Class[_] = {

        return if (!pc.getInterfaces().contains(classOf[ProxyTag])) {
          pc;
        } else {
          val index = pc.getName().indexOf("$");
          if (index == (-1)) {
            pc;
          } else {
            Class.forName(pc.getName().substring(0, index));
          }
        }
      }
    }
  }

  implicit def classGetDeclaredFieldEx(cls: Class[_]) = {
    new {
      @throws(classOf[NoSuchFieldException])
      def getDeclaredField2(name: String): Field = {
        try {
          val f = cls.getDeclaredField(name);
          return f;
        } catch {
          case e: java.lang.NoSuchFieldException => {
            var supercls = cls.getSuperclass();
            while (!supercls.equals(classOf[Object])) {
              try {
                val f = supercls.getDeclaredField(name);
                return f;
              } catch {
                case e: java.lang.NoSuchFieldException => {
                  supercls = supercls.getSuperclass();
                }
              }
            }
          }
        }

        //return null;
        throw new NoSuchFieldException;
      }
    }
  }

  //  implicit def httpRequestGetBoolean(req: HttpServletRequest) = {
  //    new {
  //      def getAttributeBoolean(name: String, defaultVal: Boolean): Boolean = {
  //        return if (req.getAttribute(name) == null) { defaultVal } else { req.getAttribute(name).asInstanceOf[Boolean] };
  //      }
  //
  //    }
  //  }
  //
  //  implicit def httpRequestIsInclude(req: HttpServletRequest) = {
  //    new {
  //      def isInc(): Boolean = isInclude(req);
  //    }
  //  }
  //
  //  implicit def httpRequestGetCacheKey(req: HttpServletRequest) = {
  //    new {
  //      def getCacheKey(): String = {
  //        return if (isInclude(req))
  //          getIncludeUrlKey(req);
  //        else
  //          getUrlKey(req);
  //      }
  //
  //      def getCacheKey(extend: String): String =
  //        {
  //          getCacheKey + "$$" + extend;
  //        }
  //    }
  //  }
  //
  //  def isInclude(req: HttpServletRequest) = (req.getAttribute("javax.servlet.include.request_uri") != null);
  //
  //  def getUrlKey(req: HttpServletRequest): String = req.getRequestURI() + (if (req.getQueryString() == null) "" else "?" + req.getQueryString());
  //
  //  def getIncludeUrlKey(req: HttpServletRequest): String = getUrlKey(req) + "_$inculde$_" +
  //    req.getAttribute("javax.servlet.include.request_uri") +
  //    (if (req.getAttribute("javax.servlet.include.query_string") == null) "" else "?"
  //      + req.getAttribute("javax.servlet.include.query_string"));

}